#include "theater.h"
/************************************************
 *
 *  start for the manager
 *
 ************************************************/
void randToBreak(char * lockWaiting, Employee clerk[], int count, char *noClerk, char * cNoClerk, char* cBreak)
{
    int i = 0;
    int temp;
    int temp1;
    Employee * current;
    /* lock to get in line*/
    AcquireLock(lockWaiting);
    for (i = 0; i < count; ++i)
    {
        current=&clerk[i];
        temp=getMV(current->isBreak);
        if (temp) continue;
        temp=getMV(current->waitingSize);
        temp1=getMV(current->waitingSize);
        if (!temp)
        {
            /* rand to break*/
            if (rand()%20 == 0)
            {
                setMV( current->isBreak,true);
                /* signal the waiting customer*/
                BroadcastCV(lockWaiting, current->lineCondition);
                temp=getMV(current->isBusy);
                if (!temp)
                {
                    AcquireLock(current->lock );
                    SignalCV(current->lock, current->msgCondition);
                    ReleaseLock(current->lock);
                }
                Printf("Manager has told %s [%d] to go on break.\n", current->employeeType, i);
            }
        }
        else if ( temp1< 3)
        {
            int j = 0;
            for (j = 0; j < count; ++j)
            {
                if (i == j) continue;
                temp=getMV(clerk[j].isBreak);
                if (!temp)
                {
                    break;
                }
            }
          /*  if (j != count && rand()%5 == 0)*/
           if (j != count && rand()%20 == 0)
            {
                setMV(current->isBreak,true);
                /* signal the waiting customer*/
                BroadcastCV(lockWaiting,current->lineCondition);

                /* if not busy, manager should signal clerk to get break*/
                temp=getMV(current->isBusy);
                if (!temp)
                {
                    AcquireLock(current->lock);
                    SignalCV(current->lock,current->msgCondition);
                    ReleaseLock(current->lock);
                }
                Printf("Manager has told %s [%d] to go on break.\n", current->employeeType, i);
            }
        }
        else if (temp1> 5)
        {
            /*int j = 0;
            for (j = 0;j < count; ++j) {
                if (i == j) continue;
                if (clerk[j]->getIsBreak()) {
                    clerk[j]->setIsBreak(false);
                    break;
                }
            }*/
            SignalCV(lockWaiting, cBreak);

        }
    }
    /* if no clerk work and customers come, have to ask one to off break*/
    temp=getMV(noClerk);
    if (temp)
    {
        setMV( noClerk , false);
        /* signal to get one clerk*/
        SignalCV(lockWaiting, cBreak);
        /* ? should get resp from clerk*/
        /* signal the customer*/
        BroadcastCV(lockWaiting,cNoClerk);
    }
    ReleaseLock(lockWaiting);
}

int main()
{
    int i;
    int temp;
    int temp1;
   initTheater();
    while (1)
    {
       /* randToBreak(lBuyTickets, tc,getMV(tcNumber), noTicketClerk, cNoTicketClerk, cBreakTicketClerk);
        randToBreak(lBuyFood, cc, getMV(ccNumber), noConcessionClerk, cNoConcessionClerk, cBreakConcessionClerk);
        randToBreak(lCheckTickets, tt,getMV( ttNumber), noTicketTaker, cNoTicketTaker, cBreakTicketTaker);
        /*to make sure whether to ask the ticket taker to take the tickets or not*/
        AcquireLock(lMovieState);
        temp=getMV(movieState);
        if (temp == 0)
        {
            AcquireLock(lTicketTaken);
            temp=getMV(stopTicketTaken);
            if (temp)
            {
                setMV(stopTicketTaken , false);
                /* set state to 1*/
                setMV(movieState , 1);
                setMV(ticketTaken , 0);
                /* ask customer and ticket clert to start ticket taken*/
                BroadcastCV(lTicketTaken,cTicketTaken);
            }
            ReleaseLock(lTicketTaken);
        }
        ReleaseLock(lMovieState);
        /*end start taken*/
        /*start a movie or not*/
        AcquireLock(lMovieState);
        temp=getMV(movieState);
        if (temp == 1)
        {
            AcquireLock(lTicketSold);
            AcquireLock(lTicketTaken);
            AcquireLock(currentCustomerSeatedlock);
            if ((getMV(stopTicketTaken) || getMV(totalTicketTaken) == getMV(totalTicketSold)) && (getMV(ticketTaken) == getMV(currentCustomerSeated) && getMV(ticketTaken) != 0))
            {
                setMV( stopTicketTaken , true);
                setMV(movieState , 2);
                AcquireLock(managerAskMTplaylock);
                setMV(managerAskMTPlay , true);
                SignalCV(managerAskMTplaylock, mr.msgCondition);
                ReleaseLock(managerAskMTplaylock);
            }
            ReleaseLock(currentCustomerSeatedlock);
            ReleaseLock(lTicketTaken);
            ReleaseLock(lTicketSold);
        }
        ReleaseLock(lMovieState);
        /**/
        for (i = 0; i < 1000; ++i)
        {
            ;
        }
        /* if all customer leave, collect money*/
        AcquireLock(lCustomerLeft);
        if (getMV(customerLeft) == 0)
        {
            /*collect money*/
            AcquireLock(lAmount);
            for (i = 0; i < getMV(tcNumber); ++i)
            {
                temp=getMV(ticketClerkAmount[i]);
                addMVbyValue(totalAmount ,temp);
                Printf("Manager collected [%d] from TicketClerk[%d].\n", getMV( ticketClerkAmount[i]), i);
                setMV( ticketClerkAmount[i] , 0);
            }

            for (i = 0; i < getMV(ccNumber); ++i)
            {
                temp=getMV(concessionClerkAmount[i]);
                addMVbyValue(totalAmount,temp);
                Printf("Manager collected [%d] from ConcessionClerk[%d].\n",getMV( concessionClerkAmount[i]), i);
                setMV(concessionClerkAmount[i] , 0);
            }
            Printf("Total money made by office = [%d]\n", getMV(totalAmount));
            ReleaseLock(lAmount);
            AcquireLock(lTicketTaken);
            Printf("Total tickets sold by office = [%d]\n", getMV(totalTicketSold));
            ReleaseLock(lTicketTaken);
            AcquireLock(lTicketSold);
            Printf("Total tickets taken by office = [%d]\n",getMV( totalTicketTaken));
            ReleaseLock(lTicketSold);
            /**/
            ReleaseLock(lCustomerLeft);
	     setMV(closeTheater, true);
	     for (i = 0; i < getMV(tcNumber); ++i)
            {
                AcquireLock(tc[i].lock);
	         SignalCV(tc[i].lock, tc[i].msgCondition);
	         ReleaseLock(tc[i].lock);
            }
	      for (i = 0; i < getMV(ccNumber); ++i)
            {
                AcquireLock(cc[i].lock);
	         SignalCV(cc[i].lock, cc[i].msgCondition);
	         ReleaseLock(cc[i].lock);
            }
            for (i = 0; i < getMV(ttNumber); ++i)
            {
                AcquireLock(tt[i].lock);
	         SignalCV(tt[i].lock, tt[i].msgCondition);
	         ReleaseLock(tt[i].lock);
            }
	         AcquireLock(managerAskMTplaylock);
                SignalCV(managerAskMTplaylock, mr.msgCondition);
                ReleaseLock(managerAskMTplaylock);
            break;
        }
        ReleaseLock( lCustomerLeft);
    }
    Exit(0);
}

